//vue3自定义指令
import pinia from "@/store";
import useUserStore from "@/store/modules/user";
import { Directive, DirectiveBinding, type App } from "vue";
// import App from "./App.vue";
const permission = [
  "jc-zs:shop:create",
  "jc-zs:shop:edit",
  //   "jc-zs:shop:delete",
];
const userId = localStorage.getItem("userId") as string;

/**
 * 根据元素绑定的权限许可值，通过上传的许可值比较判断是否显示
 * @param el 元素
 * @param bingding 元素绑定的权限许可值
 */
export const vPremShow: Directive<HTMLElement, string> = (el, bingding) => {
  if (!permission.includes(userId + ":" + bingding.value)) {
    el.style.display = "none";
  }
};

/**
 * div元素可拖拽指令
 * @param el
 * @param _
 */
export const vMove: Directive<any, void> = (
  el: HTMLElement,
  _: DirectiveBinding
) => {
  let moveEle = el.firstElementChild as HTMLDivElement;
  const mouseDown = (e: MouseEvent) => {
    let x = e.clientX - el.offsetLeft;
    let y = e.clientY - el.offsetTop;
    const move = (e: MouseEvent) => {
      el.style.left = e.clientX - x + "px";
      el.style.top = e.clientY - y + "px";
    };
    document.addEventListener("mousemove", move);
    document.addEventListener("mouseup", () => {
      document.removeEventListener("mousemove", move);
    });
  };
  moveEle.addEventListener("mousedown", mouseDown);
};

/**
 * 图片懒加载vue3指令
 * @param el
 * @param bingding
 */
export const vLazy: Directive<HTMLImageElement, string> = async (
  el,
  bingding
) => {
  const def = await import("@/assets/vue.svg");
  el.src = def.default;
  const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        window.setTimeout(() => {
          el.src = bingding.value;
        }, 2000);

        observer.unobserve(el);
      }
    });
  });
  observer.observe(el);
};

const useStore = useUserStore(pinia);

/**
 * 自定义指令；
 * 判断user参考的buttons组里包含指令中的名称，包含就显示；达到权限控制的功能
 * @param app 
 */
export const isHasBtn = (app: App) => {
  app.directive("has", {
    mounted(el: HTMLElement, options: DirectiveBinding<string>) {
      if (!useStore.buttons.includes(options.value)) {
        el.parentNode?.removeChild(el);
      }
    },
  });
};
